package com.ncmmall.application.business.member;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ncmmall.application.msm.AliYunSmsService;
import com.feijin.commons.lang.PropertiesHelps;
import com.feijin.commons.lang.Randoms;
import com.feijin.commons.securitys.MD5HashUtils;
import com.feijin.commons.webs.SyncLock;
import com.ncmmall.domain.business.distribution.DistributionRateRecord;
import com.ncmmall.domain.business.distribution.DistributionRateRecordRepository;
import com.ncmmall.domain.business.distribution.DistributionSetting;
import com.ncmmall.domain.security.role.QRole;
import com.ncmmall.domain.security.role.Role;
import com.ncmmall.domain.security.role.RoleRepository;
import com.ncmmall.domain.security.role.RoleType;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.domain.security.user.WebUserRepository;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.security.auth.login.AccountNotFoundException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

/**
 * @author linxs
 * 会员
 */
@Service
@Transactional
@Slf4j
public class MemberApplication {

    @Autowired
    private DistributionRateRecordRepository distributionRateRecordRepository;

    @Autowired
    private WebUserRepository memberRepository;

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private RoleRepository roleRepository;

    /**
     * 禁用账号
     */
    public void disable(WebUser user) {
        user.setAccountNonLocked(false);
        memberRepository.save(user);
    }

    /**
     * 启用账号
     */
    public void enabled(WebUser user) {
        user.setAccountNonLocked(true);
        memberRepository.save(user);
    }


    /**
     * 批量启用
     */
    public void enables(List<WebUser> members) {
        for (WebUser member : members) {
            enabled(member);
        }
    }

    /**
     * 批量禁用
     */
    public void disables(List<WebUser> members) {
        for (WebUser member : members) {
            disable(member);
        }
    }


    /**
     * 注册
     */
    public WebUser register(WebUser user) {
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setLastLoginTime(new Timestamp(System.currentTimeMillis()));
        user.setAccountNonLocked(true);
        user.setRole(queryChannelService.findOne(QRole.role.name.eq("MEMBER"), Role.class));
        String userNo = Randoms.generateDigitalString(12);
        user.setUserNo(userNo);
        memberRepository.save(user);
        try {
            AliYunSmsService.send(user.getMobile(), PropertiesHelps.getValue("sign_name"), "SMS_211000765", null);
        } catch (Exception e) {
            log.error("发送验证码异常");
        }
        return user;
    }

    /**
     * 注册助理账号
     */
    public WebUser registerAssistant(WebUser user) {
        user.setPassword(MD5HashUtils.asMD5(user.getPassword(), user.getUsername()));
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setAccountNonLocked(true);
        user.setRole(findRoleByName(RoleType.ANCHOR));
        user.setLiveType(2);
        user.setUserNo(RandomUtil.randomNumbers(12));
        memberRepository.save(user);
        return user;
    }


    public WebUser create(WebUser user) {

        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        user.setLastLoginTime(new Timestamp(System.currentTimeMillis()));
        user.setAccountNonLocked(true);
        user.setRole(queryChannelService.findOne(QRole.role.name.eq("MEMBER"), Role.class));

        memberRepository.save(user);

        return user;
    }

    /**
     * 登录
     */
    public WebUser login(WebUser params, String ip) {
        WebUser user = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);
        user.setLastLoginTime(new Timestamp(System.currentTimeMillis()));
        user.setAccessToken(MD5HashUtils.asMD5(user.getPassword(), String.valueOf(System.currentTimeMillis())));
        user.setRefreshToken(MD5HashUtils.asMD5(user.getUsername(), String.valueOf(System.currentTimeMillis())));
        user.setLoginIp(ip);

        if (null == user.getFirstLoginTime()) {
            user.setFirstLoginTime(new Timestamp(System.currentTimeMillis()));
        }

        memberRepository.save(user);

        return user;
    }


    /**
     * 退出登录
     */
    public void logout(String token) throws AccountNotFoundException {
        WebUser user = queryChannelService.queryOneEntity("select u.* from security_web_user u where u.accessToken = :token", ImmutableMap.of("token", token), WebUser.class);
        if (null == user) {
            throw new AccountNotFoundException("[用户不存在]");
        }

        user.setAccessToken("");
        memberRepository.save(user);

    }


    /**
     * 更改密码
     */
    public void modifyPassword(WebUser user, String password) {
        String passwordAsMd5 = MD5HashUtils.asMD5(password, user.getUsername());
        user.setPassword(passwordAsMd5);
        memberRepository.save(user);
    }


    /**
     * 修改昵称
     */
    public void modifyNickname(WebUser member, String nickname) {

        member.setNickname(nickname);
        memberRepository.save(member);

    }

    /**
     * 修改签名
     */
    public void modifySignature(WebUser member, String signature) {
        member.setSignature(signature);
        memberRepository.save(member);
    }

    /**
     * 修改头像
     */
    public void modifyAvatar(WebUser member, String avatar) {
        member.setAvatar(avatar);
        memberRepository.save(member);
    }

    /**
     * 绑定手机号码
     */
    public void bindMobile(WebUser member, String mobile) {
        member.setMobile(mobile);
        memberRepository.save(member);

    }


    /**
     * 更新用户编码
     */
    public void modifyUserNo(WebUser params) {
        WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);
        String userNo = Randoms.generateDigitalString(12);
        member.setUserNo(userNo);
        memberRepository.save(member);
    }


    /**
     * 修改性别
     */
    public void modifySex(WebUser member, int sex) {
        member.setSex(sex);
        memberRepository.save(member);
    }

    /**
     * 设置商家分销保底佣金
     */
    public void modifyGuaranteeScale(WebUser member, double scale) {
        member.setGuaranteeScale(scale);
        memberRepository.save(member);

        DistributionRateRecord record = new DistributionRateRecord()
                .setCreateTime(new Timestamp(System.currentTimeMillis()))
                .setGuaranteeScale(scale)
                .setMerchant(member);
        distributionRateRecordRepository.save(record);
    }

    /**
     * 分销邀请绑定上级
     */
    public void bindFather(WebUser member, WebUser father) {
        if (member.getFather() != null) {
            return;
        }
        member.setFather(father);
        DistributionSetting setting = queryChannelService.queryOneEntity("select * from distribution_setting order by createTime desc limit 1", new HashMap<>(), DistributionSetting.class);
        int days;
        if (setting == null || setting.getMemberBindValid() == null) {
            days = 7;
        } else {
            days = setting.getMemberBindValid();
        }
        if (days > 0) {
            member.setFatherExpires(new Timestamp(System.currentTimeMillis() + 24 * 3600 * 1000 * days));
        }
        memberRepository.save(member);
    }

    /**
     * 定时删除临时关系链
     */
    public void removeFather() {
        List<WebUser> users = queryChannelService.queryAllEntity("select * from security_web_user where father_id is not null and fatherExpires is not null and fatherExpires < now()", new HashMap<>(), WebUser.class);
        for (WebUser user : users) {
            user.setFatherExpires(null);
            user.setFather(null);
            memberRepository.save(user);
        }
    }

    /**
     * 查询用户名是否已注册
     *
     * @param username 用户名
     * @param roleType 角色类型
     */
    public boolean existByUsername(String username, RoleType roleType) {
        return memberRepository.countByUsernameAndRole(username, findRoleByName(roleType)) > 0;
    }

    /**
     * 查询手机号码已注册
     *
     * @param mobile   手机号码
     * @param roleType 角色类型
     */
    public boolean existByMobile(String mobile, RoleType roleType) {
        return memberRepository.countByMobileAndRole(mobile, findRoleByName(roleType)) > 0;
    }

    /**
     * 根据角色名称查询角色
     *
     * @param roleType 角色类型
     */
    private Role findRoleByName(RoleType roleType) {
        return roleRepository.findByName(roleType.getName());
    }

    public WebUser findAssistantByUsername(String username) {
        return memberRepository.findByUsernameAndRoleAndLiveType(username, findRoleByName(RoleType.ANCHOR), 2);
    }

    /**
     * 微信登录
     *
     * @param username  微信手机号码
     * @param openId    用户openId
     * @param ipAddress 登录ip地址
     * @return 平台用户
     */
    public WebUser wechatLogin(String username, String openId, String ipAddress) {
        synchronized (SyncLock.getLock(username)) {
            WebUser user = queryChannelService.findFirst("select u from WebUser u where u.username = :username and (u.role.name = 'MEMBER' or u.role.name = 'ANCHOR') ", ImmutableMap.of("username", username), WebUser.class);
            if (user == null) {
                user = new WebUser();
                user.setUsername(username);
                user.setMobile(username);
                user.setPassword(MD5HashUtils.asMD5("123456", username));
                user.setOpenId(openId);
                register(user);
            }
            login(user, ipAddress);
            return user;
        }
    }

    /**
     * app 微信注册
     *
     * @param unionId 微信唯一标识
     * @param mobile  绑定的手机号码
     * @return 注册的用户
     */
    public WebUser appWechatRegister(String unionId, String mobile) {
        synchronized (SyncLock.getLock(unionId)) {
            WebUser user = queryChannelService.findFirst("select u from WebUser u where u.mobile = :mobile and (u.role.name = 'MEMBER' or u.role.name = 'ANCHOR')", ImmutableMap.of("mobile", mobile), WebUser.class);
            if (user != null) {
                if (StrUtil.isNotBlank(user.getUnionId())) {
                    throw new IllegalArgumentException("手机号码已被绑定");
                }
                user.setUnionId(unionId);
                memberRepository.save(user);
            } else {
                user = new WebUser();
                user.setUnionId(unionId);
                user.setUsername(mobile);
                user.setMobile(mobile);
                user.setPassword(RandomUtil.randomNumbers(8));
                register(user);
                memberRepository.save(user);
            }
            return user;
        }
    }


}
